﻿


using IotContract.Configs;
using IotContract.Dtos.Remotes.Request;
using IotContract.Dtos.Servers;
using IotContract.Dtos.Servers.Pushs;
using IotContract.Enums;
using IotContract.Grpcs;
using IotContract.Interfaces;
using IotContract.Models;
using IotContract.Models.Clients;
using IotContract.Models.Mqtt;
using IotContract.Models.Process;
using IotContract.Models.Webs;
using IotServerService.Entities;
using IotServerService.Services;
using IotServerService.Services.Datas;
using IotServerService.Services.Datas.Managers;
using Mapster;
using MQTTnet.Server;
using ProtoBuf.Grpc;
using System.Collections.Generic;
using System.ServiceModel;
using XT.Common.Config;
using XT.Common.Extensions;

namespace IotServer.Grpcs;
/// <summary>
/// 设备连接配置交互
/// </summary>
public class ConnectGrpcService : IConnectGrpcService
{
    
    private readonly DbService _dbService;
    private readonly IConnectDataService _connectDataService;
    private readonly IServerMainManager _serverMainManager;
    private readonly IMqttServerService _mqttService;
    public ConnectGrpcService(DbService dbService,IConnectDataService connectDataService,IServerMainManager manager, IMqttServerService mqttService)
    {
        _dbService = dbService;
        _connectDataService = connectDataService;
        _serverMainManager = manager;
        _mqttService = mqttService;
    }
    /// <summary>
    /// 获取url地址
    /// </summary>
    /// <returns></returns>
    [OperationContract]
    public async Task<GrpcReturn<AddressConfig>> GetUrlAddress()
    {

        return new GrpcReturn<AddressConfig>
        {
            IsSuccess = true,
            Data = _connectDataService.AddressConfig
        };
    }
    /// <summary>
    /// 连接命令
    /// </summary>
    /// <param name="client"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<GrpcReturn<ClientStatusReturn>> ConnectCommand(ClientConnectCommand client)
    {
        var result =await new Func<Task<ProgramInfo>>(() => _dbService.AddProgram(client)).ProtectFunc();

        if (result.Item2.IsNotNullOrEmpty())
        {
            return new GrpcReturn<ClientStatusReturn>
            {
                Msg = result.Item2
            };
        }
        return new GrpcReturn<ClientStatusReturn>
        {
            IsSuccess = true,
            Data = new ClientStatusReturn
            {
                IsEnable = 1,
                Name = result.Item1.Name,
                ProgramId = result.Item1.Id
            }
        };
    }

    /// <summary>
    /// 状态命令
    /// </summary>
    /// <param name="client"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<GrpcReturn<ClientStatusReturn>> StatusCommand(ClientStatusCommand client)
    {
        var result =await new Func<Task<ProgramStatus>>(() => _dbService.AddProgramStatus(client)).ProtectFunc();
        if (result.Item2.IsNotNullOrEmpty())
        {
            return new GrpcReturn<ClientStatusReturn>
            {
                Msg = result.Item2
            };
        }
        return new GrpcReturn<ClientStatusReturn>
        {
            IsSuccess = true,
            Data = new ClientStatusReturn
            {
                IsEnable = result.Item1.IsEnable
            }
        };
    }
    /// <summary>
    /// 控制命令
    /// </summary>
    /// <param name="control"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> ControlCommand(ClientControlCommand control)
    {
        bool result= await  _serverMainManager.AddControl(control);

        return new GrpcReturn<string>
        {
            IsSuccess = result
        };
    }

    /// <summary>
    /// 控制命令
    /// </summary>
    /// <param name="controls"></param>
    /// <returns></returns>   
    public async Task<GrpcReturn<string>> ControlCommands(List<ClientControlCommand> controls)
    {
        string error = string.Empty;
        foreach(var control in controls)
        {
           var result= await _serverMainManager.AddControl(control);

            if (!result)
            {
                error = "Equip Status Error" ;
            }
        }
        if (error.IsNotNullOrEmpty())
        {
            return new GrpcReturn<string> { Msg = error };
        }
        return new GrpcReturn<string> { IsSuccess = true };
    }
    /// <summary>
    /// 完成任务
    /// </summary>
    /// <param name="fmsJobCompleteRequest"></param>
    /// <returns></returns>
   public async Task<GrpcReturn<string>> CompleteJob(FmsJobCompleteRequest fmsJobCompleteRequest)
    {
      var result=await  _serverMainManager.CompleteJob(fmsJobCompleteRequest);

        if (result.IsNullOrEmpty())
        {
            return new GrpcReturn<string> { IsSuccess = true };
        }
        else
        {
            return new GrpcReturn<string> { Msg = result };
        }
    }
    /// <summary>
    /// 添加写入命令
    /// </summary>
    /// <param name="commands"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> AddWriteCommand(List<OperationWriteCommand> commands)
    {
       bool result= await _serverMainManager.AddWrites(commands);
        return new GrpcReturn<string>
        {
            IsSuccess = result
        };
    }
    /// <summary>
    /// 请求推送的数据
    /// </summary>
    /// <param name="commands"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<PushEquipWeb>>> RequestPushEquips(List<ClientRequestCommand> commands)
    {
        var datas= await _serverMainManager.GetEquips<PushEquipDto>(commands);

        return new GrpcReturn<List<PushEquipWeb>>
        {
            Data = datas.Adapt<List<PushEquipWeb>>(),
            IsSuccess = true
        };
    }
    /// <summary>
    /// 请求服务端数据
    /// </summary>
    /// <param name="commands"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<PushEquipDto>>> RequestServerEquips(ClientRequestCommand command)
    {
        var datas = await _serverMainManager.GetEquips<PushEquipDto>(command);

        return new GrpcReturn<List<PushEquipDto>>
        {
            Data = datas.Adapt<List<PushEquipDto>>(),
            IsSuccess = true
        };
    }
    /// <summary>
    /// 请求推送的点位
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<PushTagWeb>>> RequestPushTags(ClientRequestCommand command)
    {
        var datas = await _serverMainManager.GetEquips<PushEquipDto>(command);

        if (datas.Count > 0 && datas.FirstOrDefault().HasTags)
        {

            // 利用map转换出点位数据
            var tags = datas.FirstOrDefault().Adapt<PushSiemensDto>().Tags;
            var webs= new GrpcReturn<List<PushTagWeb>>
            {
                IsSuccess = true,
                Data = tags.Adapt<List<PushTagWeb>>(),
               
            };
            return webs;
        }
        else
        {
            return new GrpcReturn<List<PushTagWeb>> { };
        }

       
    }


    /// <summary>
    /// 读取所有程序控制指令
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async IAsyncEnumerable<ClientControlCommand> ReadControlCommand(ClientControlCommand command, CallContext context = default)
    {
        await foreach(var data in _connectDataService.ReadControl(command.ProgramId, context.CancellationToken))
        {
            yield return data;
        }  
    }


    /// <summary>
    /// 请求设备数据命令
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<IotEquipDto>>> RequestEquipsCommand(ClientRequestCommand request)
    {
       var result= await _connectDataService.GetEquips(request);
        if (result.Item2.IsNotNullOrEmpty())
        {
            return new GrpcReturn<List<IotEquipDto>>
            {
                Msg = result.Item2
            };
        }
        return new GrpcReturn<List<IotEquipDto>>
        {
            IsSuccess = true,
            Data = result.Item1
        };
    }

    /// <summary>
    /// 请求设备点位数据命令
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    
   public async Task<GrpcReturn<List<EquipTagDto>>> RequestTagsCommand(ClientRequestCommand request)
    {
        var result = await _connectDataService.GetEquipTags(request);
        if (result.Item2.IsNotNullOrEmpty())
        {
            return new GrpcReturn<List<EquipTagDto>>
            {
                Msg = result.Item2
            };
        }
        return new GrpcReturn<List<EquipTagDto>>
        {
            IsSuccess = true,
            Data = result.Item1
        };
    }
    /// <summary>
    /// 推送设备
    /// </summary>
    /// <param name="equips"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<List<OperationWriteCommand>> PushEquips(List<PushEquipDto> equips)
    {
        var commands = await _connectDataService.PushEquips(equips);
        if (commands.Count > 0)
        {
            return commands;
        }
        return commands;
    }

    /// <summary>
    /// 请求调度数据
    /// </summary>
    /// <param name="provider"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<ProcessBaseData>>> RequestProcessDatas(ProcessProviderCommand provider)
    {

      var datas= await _serverMainManager.GetProcessDatas(provider);
      
        return new GrpcReturn<List<ProcessBaseData>>
        {
            IsSuccess = true,
            Data = datas
        };
    }

    /// <summary>
    /// 添加任务
    /// </summary>
    /// <returns>错误消息，为空成功</returns>
   public async Task<GrpcReturn<string>> AddProcessJob(ProcessJobCommand command)
    {
       var data= await _serverMainManager.AddProcessJob(command.Job, command.ProviderType);
        return new GrpcReturn<string> { Data = data,IsSuccess=data.IsNullOrEmpty() };
    }

    /// <summary>
    /// 移除任务
    /// </summary>
    /// <returns>错误消息，为空成功</returns>
    public async Task<GrpcReturn<string>> RemoveProcessJob(ProcessJobCommand command)
    {
        var data = await _serverMainManager.RemoveProcessJob(command.Job, command.ProviderType);
        return new GrpcReturn<string> { Data = data, IsSuccess = data.IsNullOrEmpty() };
    }

    /// <summary>
    /// 执行相关调度数据
    /// </summary>
    /// <param name="data"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<string>> ExecuteProcessData(ProcessJobCommand command)
    {
        var data = await _serverMainManager.ExecuteProcessData(command.Job, command.ProviderType);
        return new GrpcReturn<string> { Data = data, IsSuccess = data.IsNullOrEmpty() };
    }

    /// <summary>
    /// 添加Web控制
    /// </summary>
    /// <param name="control"></param>
    /// <returns></returns>  
    public async Task<GrpcReturn<string>> AddWebControl(WebControlModel control)
    {
      var error= await _connectDataService.AddWebControl(control);
        return new GrpcReturn<string>
        {
            IsSuccess = error.IsNullOrEmpty(),
            Msg = error
        };
    }

    /// <summary>
    /// 请求Mqtt客户端数据
    /// </summary>
    /// <param name="provider"></param>
    /// <returns></returns>
    public async Task<GrpcReturn<List<MqttClientInfo>>> RequestMqttClientInfos(MqttProviderCommand provider)
    {
        
        var r =  await _mqttService.GetMqttClientInfos(provider);
        return new GrpcReturn<List<MqttClientInfo>>
        {
            IsSuccess = true,
            Data = r
        };
    }

    public async Task<GrpcReturn<MqttGrpcReturn>> StartOrStopMqttServer(MqttProviderCommand provider)
    {
        var r = await _mqttService.StartOrStopMqttServer(provider);

        return new GrpcReturn<MqttGrpcReturn>
        {
            IsSuccess = true,
            Data = r
        };
    }

    public async Task<GrpcReturn<MqttGrpcReturn>> RequestMqttServerStatus()
    {
        var r = await _mqttService.GetMqttServerStatus();

        return new GrpcReturn<MqttGrpcReturn>
        {
            IsSuccess = true,
            Data = r
        };
    }

    public async Task<GrpcReturn<MqttGrpcReturn>> StartOrStopMqttProcessData(MqttProviderCommand provider)
    {
        var r =  _mqttService.StartOrStopMqttProcessData(provider);

        return new GrpcReturn<MqttGrpcReturn>
        {
            IsSuccess = true,
            Data = r
        };
    }
    
    public async Task<GrpcReturn<MqttGrpcReturn>> GetDataPublishStatus()
    {
        var r = _mqttService.GetDataPublishStatus();
        return new GrpcReturn<MqttGrpcReturn>
        {
            IsSuccess = true,
            Data = r
        };
    }
}
